#ifndef DOCUMENT_H
#define DOCUMENT_H
#include <QImage>
#include <vector>
#include "InterpolateBase.h"
#include "exceptions.hpp"
#include "Ptr.hpp"
#include "Layer.h"
#include "AbstractAction.h"

using namespace std;
using namespace OOPUtils;


class Document : public QObject
{

  Q_OBJECT

private:

  Ptr< QRect > _pCanvasRegion;
  QSize _canvasSize;
  QImage::Format _format;
  QString _imagePath;
  QString _title;
  bool _isPreviewMode;
  Ptr< QImage > _pCompositedImage;
  Ptr< QImage > _pTempPreviewImage;

  vector< Ptr< Layer > > _layers;
  int _curLayer;
  
  Ptr< InterpolateBase > _pIterpolateMethod;

  Ptr< AbstractAction > _pAction;

  Document () {}

  Ptr< QImage > _getPreviewImage (QRect region);

//   void _calcHistogram ();

public:
  
  Document (Ptr< QImage > image, const QString & imagePath, 
    const QString & title = QString ());
  virtual ~Document ();
  


  void resize (const QSize & size);
  void translateAll (const QPoint & vec);
  Ptr< QRect > getCanvasRegion ();
  const Ptr< QRect > getCanvasRegion () const;
  QSize getCanvasSize () const { return _pCanvasRegion->size (); }
  int getCanvasWidth () const { return _pCanvasRegion->width (); }
  int getCanvasHeight () const { return _pCanvasRegion->height (); }



  void refreshCompositedImage ();
  Ptr< QImage > getCompositedImage ();
  Ptr< QImage > getPreview (QRect region);
  Ptr< QImage > getPreview ();
  Ptr< QImage > getTempPreview ();
  void openPreview (Ptr< AbstractAction > pAction);
  void closePreview ();
  bool isPreviewMode () const { return _isPreviewMode; }



  const QString & getImagePath () const { return _imagePath; }
  const QString & getTitle () const { return _title; }
  const QImage::Format getFormat () const { return _format; }
  



  Ptr< Layer > getLayer (int index);
  const Ptr< Layer > getLayer (int index) const;
  void setCurrentLayer (int index);
  Ptr< Layer > getCurrentLayer ();
  const Ptr< Layer > getCurrentLayer () const;
  void addLayer (Ptr< Layer > pNewLayer);
  int getLayerCount () const;



  void setInterpolate (Ptr< InterpolateBase > pInterpolateMethod) { _pIterpolateMethod = pInterpolateMethod; }
  Ptr< InterpolateBase > getInterpolate () { return _pIterpolateMethod; }
  const Ptr< InterpolateBase > getInterpolate () const { return _pIterpolateMethod; }


//   const int * getHistogram () const { return _histogram; }
//   int * getHistogram () { return _histogram; }

public slots:

//   void refreshMode ();

//   void refreshInfo ();
};

#endif // IMAGEINFO_H
